package com.magina.project.mgdb.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassnName :ConcurrentDemoController
 * @Author： Magina.Hu
 * @Date： 2019/5/6
 * @Description：num++是否线程安全.jdk1.8的concurrent包下面的原子数值类型操作
 * @Version: V1.0
 * Copyright (c) 2019-2020 .All rights reserved.
 */
@RestController
@RequestMapping("/concurrent")
public class ConcurrentDemoController {

    public static int count1 = 0;
    public static volatile int count2 = 0;//volatile仅仅保证变量在线程间保持可见性，却依然不能保证非原子性的操作。
    public static volatile AtomicInteger count3 = new AtomicInteger(0);

    @GetMapping("/testAtomicInteger")
    public ResponseEntity testAtomicInteger() throws Exception {
        Long initTime = System.currentTimeMillis();
        testAtomicityNumber1();
        testAtomicityNumber2();
        testAtomicityNumber3();
        return ResponseEntity.ok(String.format("耗时:%s",System.currentTimeMillis()-initTime));

    }

    private void testAtomicityNumber1() {
        for (int i = 0; i < 10000; i++) {
//            new Thread() {
//                public void run() {
//                    count1++;
//                }
//            }.start();
            new Thread(() -> {
                count1++;
            }).start();
        }
        System.out.println("count1: " + count1);
    }

    private void testAtomicityNumber2() throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            new Thread() {
                public void run() {
                    for (int j = 0; j < 100; j++) {
                        count2++;
                    }
                }
            }.start();
        }
        Thread.sleep(1000);
        System.out.println("volatile count: " + count2);
    }

    private void testAtomicityNumber3() throws InterruptedException {
        for (int i = 0; i < 100; i++) {
//            new Thread() {
//                public void run() {
//                    for (int j = 0; j < 100; j++) {
//                        count3.getAndIncrement();
//                    }
//                }
//            }.start();
            new Thread(()->{
                for (int j = 0; j < 100; j++) {
                    count3.getAndIncrement();//递增
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println("AtomicInteger count: " + count3);
    }

}
